package com.iuhao.orange.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.iuhao.orange.exception.O2OServerException;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 功能描述:
 * 手机号获取手机归属地
 *
 * @auther: yanhao
 * @param:
 * @date: 2018/9/1 17:40
 * @Description:
 */
public class PhoneUtil {
    private static final Logger logger = Logger.getLogger(PhoneUtil.class);
    //正则表达式,抽取手机归属地
//    private static final String REGEX_GET_MOBILE =
//            "(?is)(<tr[^>]+>[\\s]*<td[^>]+>[\\s]*卡号归属地[\\s]*</td>[\\s]*<td[^>]+>([^<]+)</td>[\\s]*</tr>)";


    /*private static final String REGEX_GET_MOBILE =
            "(?is)(<TR[^>]+>[\\s]*<TD[^>]+>[\\s]*卡号归属地[\\s]*</TD>[\\s]*<td[^>]+>\\D+</TD>[\\s]*</TR>)";*/


    private static final String REGEX_GET_MOBILE = "(?is)(<p><span class=\"bgreen\">归属地：</span>\\D+</p>)";


    //正则表达式,审核要获取手机归属地的手机是否符合格式,可以只输入手机号码前7位
    private static final String REGEX_IS_MOBILE = "(?is)(^1[3|4|5|6|8|7|9][0-9]\\d{4,8}$)";

    //http://shouji.supfree.net/fish.asp?cat=13757188595

    /**
     * 获得手机号码归属地
     *
     * @param mobileNumber
     * @return
     * @throws Exception
     */
    public static String getMobileAddress(String mobileNumber) throws O2OServerException {
        if (!isMobile(mobileNumber)) {
            throw new O2OServerException("手机号格式不正确");
        }
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("http://shouji.supfree.net/fish.asp?cat=" + mobileNumber);
        httpGet.setHeader("Content-Type", "gb2312");
        httpGet.setHeader("Accept", "text/html, */*; q=0.01");
        httpGet.setHeader("Accept-Encoding", "gzip, deflate,sdch");
        httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.8");
        httpGet.setHeader("Connection", "keep-alive");
        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36)");
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int httpStatusCode = response.getStatusLine().getStatusCode();
            String content = EntityUtils.toString(response.getEntity(), "gb2312");
            if (httpStatusCode != HttpStatus.SC_OK) {
                logger.error("根据手机号：" + mobileNumber + "，获取归属地失败。");
            }
            if (StringUtils.isNotBlank(content)) {
                return parseMobileFrom(content);
            }
        } catch (IOException e) {
            logger.error("根据手机号：" + mobileNumber + "，获取归属地失败。", e);
        }
        return "";
    }


    /**
     * 从www.ip138.com返回的结果网页内容中获取手机号码归属地,结果为：省份 城市
     *
     * @param htmlSource
     * @return
     */
    private static String parseMobileFrom(String htmlSource) {
        String result = "";
        Pattern p = Pattern.compile(REGEX_GET_MOBILE);
        Matcher m = p.matcher(htmlSource);
        while (m.find()) {
            if (m.start(1) > 0) {
                result = m.group(1);
                result = result.replaceAll("<p><span class=\"bgreen\">归属地：</span>", "").replace("</p>", "");
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug(" result :" + result);
        }
        return result;

    }

    /**
     * 验证手机号
     *
     * @param mobileNumber
     * @return
     */
    private static boolean isMobile(String mobileNumber) {
        Pattern p = Pattern.compile(REGEX_IS_MOBILE);
        Matcher m = p.matcher(mobileNumber);

        return m.matches();
    }

    /**
     * 功能描述:
     * 公共api接口查询手机归属地
     *
     * @auther: yanhao
     * @param:
     * @date: 2018/8/15 19:17
     * @Description:
     */
    public static String getMobilePhoneAddress(String mobileNumber) throws O2OServerException {
        if (!isMobile(mobileNumber)) {
            throw new O2OServerException("手机号格式不正确");
        }
        String url = "http://www.zhaotool.com/v1/api/lt/e10adc3949ba59abbe56e057f20f883e/" + mobileNumber;
        PhoneResult phoneResult = null;
        try {
            String result = HttpUtil.get(url);
            phoneResult = JSON.parseObject(result, PhoneResult.class);
        } catch (Exception e) {
            return getMobileAddress(mobileNumber);
        }
        if (Integer.parseInt(phoneResult.getCode()) == 900) {
            return getMobileAddress(mobileNumber);
        }
        //String mobile = phoneResult.getData().getMobile();
        String phoneArea = phoneResult.getData().getPhoneArea();
        return phoneArea;
    }


    /**
     * 测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //System.out.println(getMobileAddress("15824450179"));
        System.out.println(getMobilePhoneAddress("15824450179"));
    }


    private static class PhoneResult {

        private String code;

        private PhoneData data;

        private String sid;

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public PhoneData getData() {
            return data;
        }

        public void setData(PhoneData data) {
            this.data = data;
        }

        public String getSid() {
            return sid;
        }

        public void setSid(String sid) {
            this.sid = sid;
        }
    }

    private static class PhoneData {

        private String mobile;

        private String phoneArea;

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public String getPhoneArea() {
            return phoneArea;
        }

        public void setPhoneArea(String phoneArea) {
            this.phoneArea = phoneArea;
        }
    }
}
